home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 19 / CU Amiga Magazine's Super CD-ROM 19 (1998)(EMAP Images)(GB)[!][issue 1998-02].iso / CUCD / Programming / LEDA / source / src / window / _leda_window.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-16  |  21.6 KB  |  986 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  3.1c
  4. +
  5. +
  6. +  _leda_window.c
  7. +
  8. +
  9. +  Copyright (c) 1994  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15.  
  16. // defines the LEDA_WINDOW operations declared in <LEDA/leda_window.h>
  17. // using the basic graphics routines from <LEDA/impl/x_basic.h>
  18.  
  19. #include <LEDA/leda_window.h>
  20. #include <LEDA/impl/x_basic.h>
  21.  
  22. #include <stdio.h>
  23. #include <string.h>
  24. #include <ctype.h>
  25. #include <stdlib.h>
  26. #include <math.h>
  27.  
  28. color::color(const char* name) { col_index = new_color(name);  }
  29.  
  30. color::color(int i ) { col_index = i;  }
  31.  
  32. color FG_color = black;
  33. color BG_color = white;
  34.  
  35.  
  36. void LEDA_WINDOW::flush() { flush_display(); }
  37.  
  38. void LEDA_WINDOW::set_frame_label(const char* label) 
  39. { ::set_header(draw_win,label); }
  40.  
  41. int LEDA_WINDOW::load_text_font(const char* fname) 
  42. { return ::load_text_font(fname); }
  43.  
  44. int LEDA_WINDOW::load_bold_font(const char* fname) 
  45. { return ::load_bold_font(fname); }
  46.  
  47. int LEDA_WINDOW::load_message_font(const char* fname) 
  48. { return ::load_message_font(fname); }
  49.  
  50. int LEDA_WINDOW::set_font(const char* fname) 
  51. { return ::set_font(fname); }
  52.  
  53. void LEDA_WINDOW::reset_frame_label() 
  54. { ::set_header(draw_win,default_frame_label); }
  55.  
  56. void LEDA_WINDOW::set_grid_mode(int i) 
  57. { if (i != grid_mode) init(xmin(),xmax(),ymin(),i); }
  58.  
  59. drawing_mode LEDA_WINDOW::set_mode(drawing_mode m) 
  60. { drawing_mode save = drawing_mo;
  61.   drawing_mo = m;
  62.   ::set_mode(m);
  63.   return save;
  64.  }
  65.  
  66. int LEDA_WINDOW::set_line_width(int w)
  67. { if (w < 1) w = 1;
  68.   int save = line_width;
  69.   line_width = w;
  70.   ::set_line_width(w);
  71.   return save;
  72.  }
  73.  
  74. line_style LEDA_WINDOW::set_line_style(line_style s)
  75. { line_style save = line_st;
  76.   line_st = s;
  77.   ::set_line_style(s);
  78.   return save;
  79.  }
  80.  
  81. int LEDA_WINDOW::set_node_width(int w)
  82. { if (w < 1) w = 1;
  83.   int save = node_width;
  84.   node_width = w;
  85.   return save;
  86.  }
  87.  
  88. text_mode LEDA_WINDOW::set_text_mode(text_mode m)
  89. { text_mode save = text_mo;
  90.   text_mo = m;
  91.   return save;
  92.  }
  93.  
  94.  
  95. int LEDA_WINDOW::read_event(int& k, double& x, double& y)
  96. { LEDA_WINDOW* w=0;
  97.   int e = event_handler(w,1);
  98.   while (w != this) e = event_handler(w,1);
  99.   x = mouse_xreal;
  100.   y = mouse_yreal;
  101.   k = mouse_key;
  102.   return e;
  103.  }
  104.  
  105. int LEDA_WINDOW::get_event(int& k, double& x, double& y)
  106. { LEDA_WINDOW* w=0;
  107.   int e = event_handler(w,0);
  108.   while (e != no_event && w != this) e = event_handler(w,0);
  109.   x = mouse_xreal;
  110.   y = mouse_yreal;
  111.   k = mouse_key;
  112.   return e;
  113.  }
  114.  
  115. void LEDA_WINDOW::put_back_event() { ::put_back_event(); }
  116.  
  117.  
  118. int LEDA_WINDOW::event_handler(LEDA_WINDOW*& w, int blocking)
  119. {
  120.   char s[32];
  121.   Window win;
  122.  
  123.   int   val,x,y,e;
  124.  
  125.   unsigned long t;
  126.  
  127.   if (blocking)
  128.      e = get_next_event(&win, &val, &x, &y, &t);
  129.   else
  130.      e = check_next_event(&win, &val, &x, &y, &t);
  131.  
  132.   for(int i = 0; i<count && window_list[i]->draw_win != win; i++); 
  133.  
  134.   if (i >= count)  return no_event;
  135.  
  136.   w = window_list[i];
  137.  
  138.   active_window = w;
  139.  
  140.   switch (e) {
  141.  
  142.   case configure_event:
  143.            if (w->xdots != x || w->ydots != y)
  144.            { drawing_mode save = w->set_mode(src_mode);
  145.              w->init(w->min_xcoord,w->max_xcoord,w->min_ycoord,w->grid_mode);
  146.              w->set_mode(save);
  147.             }
  148.            break;
  149.  
  150.  
  151.   case button_press_event:
  152.            w->mouse_key = val;
  153.            w->mouse_xpix = x;
  154.            w->mouse_ypix = y;
  155.            w->mouse_press_time = t;
  156.            break;
  157.  
  158.   case button_release_event:
  159.            w->mouse_key = val;
  160.            w->mouse_xpix = x;
  161.            w->mouse_ypix = y;
  162.            w->mouse_release_time = t;
  163.            break;
  164.  
  165.   case motion_event:
  166.  
  167.          w->mouse_xpix = x;
  168.          w->mouse_ypix = y;
  169.  
  170.          if (w->grid_mode) w->cursor();
  171.  
  172.          w->mouse_xreal =  w->min_xcoord + ((double)w->mouse_xpix)/w->scaling;
  173.          w->mouse_yreal =  w->max_ycoord - ((double)w->mouse_ypix)/w->scaling;
  174.         
  175.          if (blocking)
  176.          { if (w->grid_mode)
  177.            { int g = w->grid_mode;
  178.              w->mouse_xreal = g*(int)(w->mouse_xreal/g +((w->mouse_xreal>0) ? 0.5:-0.5));
  179.              w->mouse_yreal = g*(int)(w->mouse_yreal/g +((w->mouse_yreal>0) ? 0.5:-0.5));
  180.              w->mouse_xpix  = w->xpix(w->mouse_xreal);
  181.              w->mouse_ypix  = w->ypix(w->mouse_yreal);
  182.              w->cursor();
  183.             }
  184.      
  185.            if (w->show_coord && blocking)
  186.            { sprintf(s,"%8.2f %8.2f\0", w->mouse_xreal,w->mouse_yreal);
  187.              show_coordinates(win,s);
  188.             }
  189.           
  190.            if (w->mouse_action && w == read_window) /* user defined action */
  191.            { w->mouse_action(w->mouse_last_xreal,w->mouse_last_yreal);
  192.              w->mouse_action(w->mouse_xreal,w->mouse_yreal);
  193.             }
  194.           }
  195.       
  196.          w->mouse_last_xreal = w->mouse_xreal;
  197.          w->mouse_last_yreal = w->mouse_yreal;
  198.  
  199.      }
  200.  
  201.   return e;
  202. }
  203.  
  204.  
  205. int LEDA_WINDOW::read_mouse(int kind, double xstart, double ystart, double &x, double &y)
  206.   // 0: point, 1: segment, 2:rectangle, 3: circle 
  207.  
  208.   switch(kind) {
  209.   case  0: return read_mouse_action(mouse_default_action,xstart,ystart,x,y);
  210.   case  1: return read_mouse_action(mouse_segment_action,xstart,ystart,x,y);
  211.   case  2: return read_mouse_action(mouse_rect_action,xstart,ystart,x,y);
  212.   case  3: return read_mouse_action(mouse_circle_action,xstart,ystart,x,y);
  213.   default: return read_mouse_action(mouse_default_action,xstart,ystart,x,y);
  214.   }
  215.  
  216. }
  217.  
  218.  
  219. int LEDA_WINDOW::get_button(double &x, double &y)
  220. { mouse_key = 0;
  221.   drawing_mode s = set_mode(xor_mode);
  222.   set_read_gc();
  223.   LEDA_WINDOW* w;
  224.   int e = event_handler(w,0);
  225.   while (e != no_event && e != button_press_event && w != this) 
  226.       e = event_handler(w,0);
  227.   reset_gc();
  228.   set_mode(s);
  229.   x = mouse_xreal;
  230.   y = mouse_yreal;
  231.   return mouse_key;
  232.  }
  233.  
  234. unsigned long LEDA_WINDOW::button_press_time()  { return mouse_press_time; }
  235. unsigned long LEDA_WINDOW::button_release_time(){ return mouse_release_time; }
  236.  
  237.  
  238. int LEDA_WINDOW::read_mouse_action(mouse_action_func_ptr action, double xstart, double ystart, double &x, double &y)
  239. {
  240.   read_window = this;
  241.  
  242.   mouse_action = action;
  243.  
  244.   drawing_mode s = set_mode(xor_mode);
  245.   set_read_gc();
  246.  
  247.   mouse_key = 0;
  248.  
  249.   mouse_start_xreal = xstart;
  250.   mouse_start_yreal = ystart;
  251.  
  252.   mouse_start_xpix = xpix(xstart);
  253.   mouse_start_ypix = ypix(ystart);
  254.  
  255.   if (grid_mode) cursor();
  256.  
  257.   if (show_coord)
  258.   { char s[64];
  259.     sprintf(s,"%8.2f %8.2f\0", mouse_xreal,mouse_yreal);
  260.     show_coordinates(draw_win,s);
  261.    }
  262.  
  263.   if (mouse_action) mouse_action(mouse_last_xreal,mouse_last_yreal);
  264.  
  265.   LEDA_WINDOW* w;
  266.  
  267.   while (event_handler(w,1) != button_press_event || w != this);
  268.  
  269.   if (mouse_action) mouse_action(mouse_xreal,mouse_yreal);
  270.  
  271.   if (grid_mode) cursor();
  272.  
  273.   x = mouse_xreal;
  274.   y = mouse_yreal;
  275.  
  276.   reset_gc();
  277.   set_mode(s);
  278.  
  279.   mouse_action = mouse_default_action;
  280.  
  281.   return mouse_key;
  282. }
  283.  
  284.  
  285. void LEDA_WINDOW::close() 
  286. { if (draw_win)
  287.   { int i = 0;
  288.     while (window_list[i] != this) i++;
  289.     count--;
  290.     window_list[i] = window_list[count];
  291.     close_window(draw_win); 
  292.     draw_win = 0;
  293.     if (count==0) close_display(); 
  294.    }
  295.  }
  296.  
  297.  
  298.  
  299. LEDA_WINDOW::LEDA_WINDOW(float width, float height, float xpos, float ypos, 
  300.                                                       const char *frame_label)
  301. { ref_count = 1;
  302.   state = 1;
  303.   draw_win = 0;
  304.   open(int(width),int(height),int(xpos),int(ypos),frame_label);
  305.  }
  306.  
  307.  
  308. LEDA_WINDOW::LEDA_WINDOW(float width, float height, const char* frame_label)
  309. { ref_count = 1;
  310.   state = 1;
  311.   draw_win = 0;
  312.   open(int(width),int(height),-3,-1,frame_label); 
  313.  }
  314.  
  315. LEDA_WINDOW::LEDA_WINDOW(const char* frame_label)
  316. { ref_count = 1;
  317.   state = 1;
  318.   draw_win = 0;
  319.   int l  =  screen_height() - 35;
  320.   if (l > 700) l = 700;
  321.   open(l,l,-3,-1,frame_label);
  322.  }
  323.  
  324. LEDA_WINDOW::LEDA_WINDOW()
  325. { ref_count = 1;
  326.   state = 1;
  327.   draw_win = 0;
  328.   //int l  =  screen_height() - 35;
  329.   //if (l > 700) l = 700;
  330.   //open(l,l,-3,-1,"");
  331.  }
  332.  
  333. LEDA_WINDOW::LEDA_WINDOW(const LEDA_WINDOW& w)
  334. { state = w.state;
  335.   ref_count = w.ref_count+1;
  336.   draw_win = w.draw_win;
  337.  }
  338.  
  339. LEDA_WINDOW::~LEDA_WINDOW() 
  340. { if (--ref_count == 0) close(); }
  341.  
  342.  
  343. LEDA_WINDOW& LEDA_WINDOW::operator=(const LEDA_WINDOW& w)
  344. { if (&w != this)
  345.   { if (--ref_count == 0) close();
  346.     state = w.state;
  347.     ref_count = w.ref_count + 1;
  348.     draw_win = w.draw_win;
  349.    }
  350.   return *this;
  351.  }
  352.  
  353.  
  354.  
  355. void LEDA_WINDOW::open(int w_width, int w_height, int w_xpos, int w_ypos, 
  356.                                                       const char *frame_label)
  357. {
  358.   if (draw_win) return;
  359.  
  360.   active_window = this;
  361.  
  362.   default_frame_label[0] = 0;
  363.  
  364.   if (frame_label) strcpy(default_frame_label,frame_label);
  365.  
  366.   if (count==0) open_display();
  367.  
  368.   window_list[count] = this;
  369.  
  370.   count++;
  371.  
  372.   if (w_xpos < 0)
  373.     switch (w_xpos) {
  374.     case -1 : w_xpos = 0;
  375.               break;
  376.     case -2 : w_xpos = (screen_width() - w_width - 10)/2;
  377.               break;
  378.     case -3 : w_xpos = (screen_width() - w_width - 10);
  379.               break;
  380.     default : w_xpos = 0;
  381.     }
  382.  
  383.   if (w_ypos < 0)
  384.     switch (w_ypos) {
  385.     case -1 : w_ypos = 0;
  386.               break;
  387.     case -2 : w_ypos = (screen_height() - w_height - 30)/2;
  388.               break;
  389.     case -3 : w_ypos = (screen_height() - w_height - 30);
  390.               break;
  391.     default : w_ypos = 0;
  392.     }
  393.  
  394.   draw_win = open_window(w_xpos, w_ypos, w_width, w_height,
  395.                          default_frame_label,"LEDA WINDOW");
  396.   set_color(black);
  397.   set_text_font();
  398.  
  399.   set_mode(src_mode);
  400.   set_line_style(solid);
  401.   set_line_width(1);
  402.   set_node_width(12);
  403.   set_text_mode(transparent);
  404.  
  405.   set_show_coordinates(1);
  406.  
  407.   redraw = 0;
  408.  
  409.   depth = display_depth();
  410.   min_xcoord = 0;
  411.   min_ycoord = 0;
  412.   max_xcoord = 0;
  413.   max_ycoord = 0;
  414.   scaling = 1;
  415.   mouse_xpix = 0;
  416.   mouse_ypix = 0;
  417.  
  418.   mesg_count = 0;
  419.  
  420.   screen_flush = 1;
  421.  
  422.   window_xpos = w_xpos;
  423.   window_ypos = w_ypos;
  424.   window_width = w_width;
  425.   window_height = w_height;
  426.  
  427.   init(0,100,0,0);
  428. }
  429.  
  430.  
  431. void LEDA_WINDOW::init(double x0, double x1, double y0, int g_mode)
  432. {
  433.  if (x0 >= x1)
  434.  { fprintf(stderr,"Illegal arguments in draw_init: x0 (%f) >= x1 (%f)\n",x0,x1);
  435.    abort();
  436.   }
  437.  
  438.   grid_mode = g_mode;
  439.  
  440.  
  441.   xdots = ::window_width(draw_win);
  442.   ydots = ::window_height(draw_win);
  443.  
  444.  
  445.   scaling = ((double)xdots)/(x1-x0);
  446.  
  447.   /* at least grid distance of 2 pixels */
  448.   if ((grid_mode) && (grid_mode*scaling < 2))
  449.   { grid_mode=0; 
  450.     fprintf(stderr,"warning: grid distance to small.\n");
  451.    }
  452.  
  453.   if (grid_mode)
  454.   { if (scaling < 1) scaling = 1;
  455.     else scaling = (int)scaling;
  456.   }
  457.  
  458.   min_xcoord = x0;
  459.   min_ycoord = y0;
  460.   max_xcoord = x0+xdots/scaling;
  461.   max_ycoord = y0+ydots/scaling;
  462.  
  463.   xorigin = (int)(-x0*scaling);
  464.   yorigin = (int)(ydots+y0*scaling);
  465.  
  466.   mouse_xreal = 0;
  467.   mouse_yreal = 0;
  468.  
  469.   clear(0);  
  470.  
  471.   if (redraw) (*redraw)();
  472.  
  473.   flush_display();
  474.  
  475. }
  476.  
  477.  
  478. void LEDA_WINDOW::draw_pix(double x, double y, int col)
  479. { set_color(col);
  480.   pixel(draw_win,xpix(x),ypix(y));
  481.   if (screen_flush) flush_display();
  482. }
  483.  
  484.  
  485. void LEDA_WINDOW::draw_segment(double x1, double y1, double x2, double y2, int col)
  486. { set_color(col);
  487.   line(draw_win, xpix(x1), ypix(y1), xpix(x2), ypix(y2));
  488.   if (screen_flush) flush_display();
  489. }
  490.  
  491.  
  492. void LEDA_WINDOW::draw_point(double x, double y, int col)
  493. { int X = xpix(x);
  494.   int Y = ypix(y);
  495.   set_color(col);
  496.   pixel(draw_win,X-2,Y-2);
  497.   pixel(draw_win,X+2,Y-2);
  498.   pixel(draw_win,X-1,Y-1);
  499.   pixel(draw_win,X+1,Y-1);
  500.   pixel(draw_win,X,Y);
  501.   pixel(draw_win,X-1,Y+1);
  502.   pixel(draw_win,X+1,Y+1);
  503.   pixel(draw_win,X-2,Y+2);
  504.   pixel(draw_win,X+2,Y+2);
  505.   if (screen_flush) flush_display();
  506. }
  507.  
  508.  
  509. void LEDA_WINDOW::draw_arc(double x0, double y0, double r1, double r2, double start, double angle, int col)
  510. { int R1 = (int)(r1*scaling);
  511.   int R2 = (int)(r2*scaling);
  512.   set_color(col);
  513.   arc(draw_win,xpix(x0),ypix(y0),R1,R2,start,angle);
  514.   if (screen_flush) flush_display();
  515. }
  516.  
  517. void LEDA_WINDOW::draw_filled_arc(double x0, double y0, double r1, double r2, double start, double angle, int col)
  518. { int R1 = (int)(r1*scaling);
  519.   int R2 = (int)(r2*scaling);
  520.   set_color(col);
  521.   fill_arc(draw_win,xpix(x0),ypix(y0),R1,R2,start,angle);
  522.   if (screen_flush) flush_display();
  523. }
  524.  
  525.  
  526. void LEDA_WINDOW::draw_node(double x0, double y0, int col)
  527. { int save = set_line_width(1);
  528.   double R = node_width/scaling;
  529.   draw_circle(x0,y0,R,col);
  530.   set_line_width(save);
  531.  }
  532.  
  533. void LEDA_WINDOW::draw_filled_node(double x0, double y0, int col)
  534. { double R = node_width/scaling;
  535.   if (depth==1 && col!=white) col = black;
  536.   draw_filled_circle(x0,y0,R,col);
  537.   if (col != black) 
  538.   { int save = set_line_width(1);
  539.     draw_circle(x0,y0,R,col);
  540.     draw_circle(x0,y0,R,black);
  541.     set_line_width(save);
  542.    }
  543.  }
  544.  
  545.  
  546. void LEDA_WINDOW::draw_text_node(double x0, double y0, char *s, int col)
  547. { text_mode t_save = set_text_mode(transparent);
  548.   set_bold_font();
  549.  
  550.   if (depth==1 && col!=black) col = white;
  551.   draw_filled_node(x0,y0,col);
  552.   
  553.   draw_ctext(x0,y0,s,col);
  554.  
  555.   if (col == black) 
  556.      draw_ctext(x0,y0,s,white);
  557.   else
  558.      draw_ctext(x0,y0,s,black);
  559.  
  560.   set_text_mode(t_save);
  561.   set_text_font();
  562. }
  563.  
  564. void LEDA_WINDOW::draw_int_node(double x0, double y0, int i, int col)
  565. { char buf[16];
  566.   sprintf(buf,"%d",i);
  567.   draw_text_node(x0,y0,buf,col);
  568.  }
  569.  
  570.  
  571. void LEDA_WINDOW::draw_edge(double x1, double y1, double x2, double y2, int col)
  572. { double dx = x2-x1;
  573.   double dy = y2-y1;
  574.   if (dx==0 && dy==0) return;
  575.   double l = node_width/(scaling*hypot(dx,dy));
  576.   x1 += l*dx;
  577.   x2 -= l*dx;
  578.   y1 += l*dy;
  579.   y2 -= l*dy;
  580.   draw_segment(x1,y1,x2,y2,col);
  581. }
  582.  
  583.  
  584.  
  585. void LEDA_WINDOW::draw_circle(double x0, double y0, double r, int col)
  586. { int R = (int)(r*scaling);
  587.   set_color(col);
  588.   circle(draw_win,xpix(x0),ypix(y0),R);
  589.   if (screen_flush) flush_display();
  590.  }
  591.  
  592.  
  593. void LEDA_WINDOW::draw_filled_circle(double x0, double y0, double r, int col)
  594. { int R = (int)(r*scaling);
  595.   set_color(col);
  596.   if (R > 0)
  597.      fill_circle(draw_win,xpix(x0),ypix(y0),R);
  598.   else
  599.      pixel(draw_win,xpix(x0),ypix(y0));
  600.   if (screen_flush) flush_display();
  601.  }
  602.  
  603.  
  604. void LEDA_WINDOW::draw_ellipse(double x0, double y0, double a, double b, int col)
  605. { int R1 = (int)(a*scaling);
  606.   int R2 = (int)(b*scaling);
  607.   set_color(col);
  608.   ellipse(draw_win,xpix(x0),ypix(y0),R1,R2);
  609.   if (screen_flush) flush_display();
  610.  }
  611.  
  612.  
  613. void LEDA_WINDOW::draw_filled_ellipse(double x0, double y0, double a, double b, int col)
  614. { int R1 = (int)(a*scaling);
  615.   int R2 = (int)(b*scaling);
  616.   set_color(col);
  617.   fill_ellipse(draw_win,xpix(x0),ypix(y0),R1,R2);
  618.   if (screen_flush) flush_display();
  619.  }
  620.  
  621.  
  622.  
  623. void LEDA_WINDOW::plot_xy(double x0, double x1, double (*f) (double), int col)
  624. {
  625.   int *xcoord;
  626.   int *ycoord;
  627.  
  628.   int x = xpix(x0);
  629.   int y_old = ypix((*f)(x0));
  630.   int i,y_new;
  631.   int size = 0;
  632.   int n = 0;
  633.  
  634.   set_color(col);
  635.  
  636.   for(x = xpix(x0)+1; x <= xpix(x1); x++)
  637.   { y_new = ypix((*f)(xreal(x)));
  638.     if (y_new > y_old)
  639.        size += (y_new-y_old+1);
  640.     else
  641.        size += (y_old-y_new+1);
  642.     y_old = y_new;
  643.    }
  644.  
  645.   xcoord = (int*) malloc(size*sizeof(int));
  646.   ycoord = (int*) malloc(size*sizeof(int));
  647.  
  648.   y_old = ypix((*f)(x0));
  649.  
  650.   for(x = xpix(x0)+1; x <= xpix(x1); x++)
  651.   { y_new = ypix((*f)(xreal(x)));
  652.     if (y_new > y_old)
  653.       for(i=y_old; i<=y_new; i++) 
  654.       { xcoord[n] = x;
  655.         ycoord[n] = i;
  656.         n++;
  657.        }
  658.     else
  659.       for(i=y_old; i>=y_new; i--) 
  660.       { xcoord[n] = x;
  661.         ycoord[n] = i;
  662.         n++;
  663.        }
  664.     y_old = y_new;
  665.   }
  666.  
  667.  pixels(draw_win,size,xcoord,ycoord);
  668.  
  669.  free((char*)xcoord);
  670.  free((char*)ycoord);
  671.  
  672.   if (screen_flush) flush_display();
  673. }
  674.  
  675.  
  676. void LEDA_WINDOW::plot_yx(double y0, double y1, double (*f) (double), int col)
  677. {
  678.   int *xcoord;
  679.   int *ycoord;
  680.  
  681.   int y;
  682.   int i,x_new;
  683.   int x_old = xpix((*f)(y0));
  684.   int size = 0;
  685.   int n = 0;
  686.  
  687.   set_color(col);
  688.  
  689.   for(y = ypix(y0)-1; y >= ypix(y1); y++)
  690.   { x_new = xpix((*f)(yreal(y)));
  691.     if (x_new > x_old)
  692.        size += (x_new-x_old+1);
  693.     else
  694.        size += (x_old-x_new+1);
  695.     x_old = x_new;
  696.    }
  697.  
  698.   xcoord = (int*) malloc(size*sizeof(int));
  699.   ycoord = (int*) malloc(size*sizeof(int));
  700.  
  701.   x_old = xpix((*f)(y0));
  702.  
  703.   for(y = ypix(y0)-1; y >= ypix(y1); y--)
  704.   {
  705.     x_new = xpix((*f)(yreal(y)));
  706.     if (x_new > x_old)
  707.       for(i=x_old; i<=x_new; i++) 
  708.       { xcoord[n] = i;
  709.         ycoord[n] = y;
  710.         n++;
  711.        }
  712.     else
  713.       for(i=x_old; i>=x_new; i--) 
  714.       { xcoord[n] = i;
  715.         ycoord[n] = y;
  716.         n++;
  717.        }
  718.     x_old = x_new;
  719.   }
  720.  
  721.  pixels(draw_win,size,xcoord,ycoord);
  722.  
  723.  free((char*)xcoord);
  724.  free((char*)xcoord);
  725.  
  726.  if (screen_flush) flush_display();
  727. }
  728.  
  729.  
  730. void LEDA_WINDOW::draw_filled_polygon(int n, double *xcoord, double *ycoord, int col)
  731. {
  732.  int* x = (int*) malloc(n*sizeof(int));
  733.  int* y = (int*) malloc(n*sizeof(int));
  734.  int i;
  735.  
  736.  for(i=0;i<n;i++)
  737.  { x[i] = xpix(xcoord[i]);
  738.    y[i] = ypix(ycoord[i]);
  739.   }
  740.  
  741.  set_color(col);
  742.  
  743.  fill_polygon(draw_win,n,x,y);
  744.  
  745.  free((char*)x);
  746.  free((char*)y);
  747.  
  748.   if (screen_flush) flush_display();
  749. }
  750.  
  751. void LEDA_WINDOW::draw_polygon(int n, double *xcoord, double *ycoord, int col)
  752. { int i;
  753.  
  754.   for(i=0;i<n-1;i++)
  755.     draw_segment(xcoord[i],ycoord[i], xcoord[i+1],ycoord[i+1],col);
  756.  
  757.   draw_segment(xcoord[n-1],ycoord[n-1],xcoord[0],ycoord[0],col);
  758.  
  759.   if (screen_flush) flush_display();
  760.  
  761.  }
  762.  
  763.  
  764. void LEDA_WINDOW::draw_rectangle(double x1, double y1, double x2, double y2, int col)
  765. { set_color(col);
  766.   rectangle(draw_win,xpix(x1),ypix(y1),xpix(x2),ypix(y2));
  767.   if (screen_flush) flush_display();
  768.  }
  769.  
  770.  
  771. void LEDA_WINDOW::draw_filled_rectangle(double x1, double y1, double x2, double y2, int col)
  772. { set_color(col);
  773.   box(draw_win,xpix(x1),ypix(y1),xpix(x2),ypix(y2));
  774.   if (screen_flush) flush_display();
  775.  }
  776.  
  777.  
  778. void LEDA_WINDOW::copy_rect(double x1, double y1, double x2, double y2, double x, double y)
  779. { ::copy_rect(draw_win,xpix(x1),ypix(y1),xpix(x2),ypix(y2),xpix(x),ypix(y));
  780.   if (screen_flush) flush_display();
  781.  }
  782.  
  783. void LEDA_WINDOW::insert_bitmap(int width, int height, char* data)
  784. { ::insert_bitmap(draw_win,width,height,data);
  785.   if (screen_flush) flush_display();
  786.  }
  787.  
  788.  
  789. void LEDA_WINDOW::clear(int col)
  790. { int x0,y0,n;
  791.   double x,y;
  792.  
  793.   int *xcoord;
  794.   int *ycoord;
  795.  
  796.   int save_lw = set_line_width(1);
  797.   line_style save_ls = set_line_style(solid);
  798.  
  799.  del_messages();
  800.  
  801.  if (depth == 1) col = 0;
  802.  
  803.  clear_window(draw_win,col);
  804.  
  805.  set_color(black);
  806.  
  807.  if (grid_mode) /* draw grid */
  808.  { n =  (int)((max_xcoord - min_xcoord)/grid_mode + 1);
  809.    n *= (int)((max_ycoord - min_ycoord)/grid_mode + 1);
  810.  
  811.    x0 = ((int)(min_xcoord/grid_mode))*grid_mode;
  812.    y0 = ((int)(min_ycoord/grid_mode))*grid_mode;
  813.  
  814.    xcoord = (int *) malloc(n*sizeof(int));
  815.    ycoord = (int *) malloc(n*sizeof(int));
  816.  
  817.    n = 0;
  818.  
  819.    for(x = x0; x<=max_xcoord; x+=grid_mode)
  820.    for(y = y0; y<=max_ycoord; y+=grid_mode)
  821.    { if (x == 0 || y == 0)
  822.         fill_circle(draw_win,xpix(x),ypix(y),1);
  823.      else
  824.         { xcoord[n] = xpix(x);
  825.           ycoord[n] = ypix(y);
  826.           n++;
  827.          }
  828.     }
  829.  
  830.    pixels(draw_win,n,xcoord,ycoord);
  831.  
  832.    free((char*)xcoord);
  833.    free((char*)ycoord);
  834.   }
  835.  
  836.  set_line_width(save_lw);
  837.  set_line_style(save_ls);
  838.  
  839.  flush_display();
  840. }
  841.  
  842.  
  843.  
  844. void LEDA_WINDOW::message(const char *s)
  845. { drawing_mode save = set_mode(xor_mode);
  846.  
  847.   mesg_list[mesg_count] = (char*)malloc(strlen(s)+1);
  848.   strcpy(mesg_list[mesg_count],s);
  849.  
  850.   mesg_count++;
  851.  
  852.   set_color(black);
  853.   set_message_font();
  854.   int h = int(1.3 * text_height("H"));
  855.   put_text(draw_win,20,10+h*mesg_count,s,0);
  856.   set_text_font();
  857.   set_mode(save);
  858.   flush_display();
  859. }
  860.  
  861.  
  862. void LEDA_WINDOW::del_messages(void)
  863. { drawing_mode save = set_mode(xor_mode);
  864.   set_color(black);
  865.   set_message_font();
  866.   int h = int(1.3 * text_height("H"));
  867.   while(mesg_count > 0)
  868.   { char* s = mesg_list[mesg_count-1];
  869.     put_text(draw_win,20,10+h*mesg_count,s,0);
  870.     mesg_count--;
  871.     free(s);
  872.    }
  873.   set_text_font();
  874.   set_mode(save);
  875.   flush_display();
  876. }
  877.  
  878.  
  879.  
  880. void LEDA_WINDOW::draw_text(double x, double y, const char *s, int col)
  881. { set_color(col);
  882.   put_text(draw_win,xpix(x),ypix(y),s,text_mo);
  883.   if (screen_flush) flush_display();
  884. }
  885.  
  886.  
  887. void LEDA_WINDOW::draw_ctext(double x, double y, const char *s, int col)
  888. { set_color(col);
  889.   put_ctext(draw_win,xpix(x),ypix(y),s,text_mo);
  890.   if (screen_flush) flush_display();
  891. }
  892.  
  893. void LEDA_WINDOW::cursor(void)
  894. { int X = xpix(mouse_xreal);
  895.   int Y = ypix(mouse_yreal);
  896.   line(draw_win, X,Y,X+10,Y);
  897.   line(draw_win, X,Y,X-10,Y);
  898.   line(draw_win, X,Y,X,Y+10);
  899.   line(draw_win, X,Y,X,Y-10);
  900. }
  901.  
  902. // define static members
  903.  
  904. LEDA_WINDOW* LEDA_WINDOW::window_list[32];
  905. LEDA_WINDOW* LEDA_WINDOW::read_window = 0;
  906. LEDA_WINDOW* LEDA_WINDOW::active_window = 0;
  907. int          LEDA_WINDOW::count = 0;
  908.  
  909. int  LEDA_WINDOW::screen_width(void)  { return display_width(); }
  910. int  LEDA_WINDOW::screen_height(void) { return display_height(); }
  911. int  LEDA_WINDOW::screen_depth(void)  { return display_depth(); }
  912.  
  913. void LEDA_WINDOW::mouse_default_action(double,double) 
  914. { /* do nothing */}
  915.  
  916. void LEDA_WINDOW::mouse_segment_action(double x, double y) 
  917. { double x0 = read_window->mouse_start_xreal;
  918.   double y0 = read_window->mouse_start_yreal;
  919.   read_window->draw_segment(x0,y0,x,y,black); 
  920.  }
  921.  
  922. void LEDA_WINDOW::mouse_rect_action(double x, double y)
  923. { double x0 = read_window->mouse_start_xreal;
  924.   double y0 = read_window->mouse_start_yreal;
  925.   read_window->draw_rectangle(x0,y0,x,y,black);
  926.  }
  927.  
  928. void LEDA_WINDOW::mouse_circle_action(double x, double y)
  929. { double x0 = read_window->mouse_start_xreal;
  930.   double y0 = read_window->mouse_start_yreal;
  931.   read_window->draw_circle(x0,y0,hypot(x-x0,y-y0),black);
  932.  }
  933.  
  934.  
  935. #include <fstream.h>
  936.  
  937. char* Read_Leda_Bitmap(const char* fname, int& w, int& h)
  938. {
  939.   ifstream bitmap(fname);
  940.  
  941.   unsigned char c1,c2;
  942.  
  943.   bitmap.get(c1);
  944.   bitmap.get(c2);
  945.   w = c2;
  946.   w *= 256;
  947.   w += c1;
  948.  
  949.   bitmap.get(c1);
  950.   bitmap.get(c2);
  951.   h = c2;
  952.   h *= 256;
  953.   h += c1;
  954.  
  955.   int n = w*h/8;
  956.  
  957.   char* map = new char[n];
  958.  
  959.   int i = 0;
  960.   while(i<n && bitmap) 
  961.   { char c;
  962.     bitmap.get(c);
  963.     if (c == char(0xff) || c == char(0x00))
  964.        { unsigned char j;
  965.          bitmap.get(j);
  966.          while (j--) map[i++] = c;
  967.         }
  968.     else 
  969.        map[i++] = c;
  970.    }
  971.  
  972.   return map;
  973. }
  974.  
  975.  
  976.  
  977. int read_mouse(LEDA_WINDOW*& w, double& x, double& y)
  978. { int e = LEDA_WINDOW::event_handler(w,1);
  979.   while (e != button_press_event) e = LEDA_WINDOW::event_handler(w,1);
  980.   x = w->mouse_xreal;
  981.   y = w->mouse_yreal;
  982.   return w->mouse_key;
  983.  }
  984.